package com.king.juc.shared.exercise;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Vector;

/**
 * 卖票问题线程安全Demo
 *      边界为count, 多个线程公用一个变量, 需要对变量进行加锁
 * @author king
 * @date 2020/10/28 17:48
 */
//@Slf4j(topic = "c.ExerciseSell")
public class ExerciseSell {

    /**
     * 线程安全
     */
    static Random random = new Random();

    public static void main(String[] args) {
        TicketWindow ticketWindow = new TicketWindow(1000);
        List<Thread> list = new ArrayList<>();
        // 用来存储卖出去多少张票
        List<Integer> sellCount = new Vector<>();
        for (int i = 0; i < 2000; i++) {
            Thread t = new Thread(() -> {
                // 分析这里的竞态条件
                int count = ticketWindow.sell(randomAmount());
                sellCount.add(count);
            });
            list.add(t);
            t.start();
        }

        list.forEach((t) -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 卖出的票求和
//        log.debug("selled count: {}", sellCount.stream().mapToInt(c -> c).sum());
        System.out.println("selled count: " + sellCount.stream().mapToInt(c -> c).sum());
        // 剩余票数
//        log.debug("remainder count: {}", ticketWindow.getCount());
        System.out.println("remainder count: " + ticketWindow.getCount());
    }

    /**
     * 生成随机数
     * @return 1 ~ 5
     */
    public static int randomAmount(){
        return random.nextInt(5) + 1;
    }
}
